/* eslint-disable */
// OCR任务的整体标注结果，用来从服务器获取数据并缓存下来
// 可以认为是浏览器端的数据层，前端直接通过操作数据层来获取和保存数据
import axios from 'axios';
import API from '@/js/api';
import LabelStorageBase from './LabelStorageBase';
import { createLabel } from '@/js/models/LabelBase.js';

const BASE_IMAGES_URL = import.meta.env.VITE_APP_API_BASE_IMAGES_URL;
const BASE_LABELS_URL = import.meta.env.VITE_APP_API_BASE_LABELS_URL;

// 本地LabelData的JS存储对象
class LabelStorageCloud extends LabelStorageBase {
    constructor() {
        super();
    }

    // 从服务端加载数据，默认page=1
    async loadDataset(dataset) {
        this.dataset_id = dataset.id;
        this.dataset_type = dataset.type;
        let response = await API.cloud.labeldata.getLabelData(dataset.id, 1, this.per_page);
        // console.log('labeldata = ', response);

        // 更新labeldata数据
        this.labeldata_pages = {};
        this.labeldata = {};

        this.labeldata_count = response.total_records;
        this.labeldata_pages[response.current_page - 1] = response.labeldata;

        return this.labeldata_count;
    }

    // 根据page_index获取对应一页的数据
    async getPageData(page_index) {
        if (page_index < 0 && page_index >= this.labeldata_pages.length) {
            return [];
        }
        return this.labeldata_pages[page_index];
    }

    // 返回labeldata数据
    // index： 在整体样本中的个数，对于调用者，page透明处理，从1开始
    async getLabelData(index) {
        if (index < 0 || index >= this.labeldata_count) {
            return {};
        }

        // 根据在整个dataset_id中的位置，判断所在的分页以及分页的索引
        let pageIndex = Math.trunc(index / this.per_page);
        let inPageIndex = index % this.per_page;
        // console.log(`pageIndex = ${pageIndex}, inPageIndex = ${inPageIndex}`);

        // 判断数据是否已经加载到本地，否则从云端加载整页数据
        if (pageIndex in this.labeldata_pages == false) {
            let response = await API.cloud.labeldata.getLabelData(this.dataset_id, pageIndex + 1, this.per_page);
            this.labeldata_pages[response.current_page - 1] = response.labeldata;
        }

        // 更新具体某一个labeldata的数据
        let label_data = this.labeldata_pages[pageIndex][inPageIndex];
        // NOTE: 优先使用this.labeldata里面的数据，因为都会及时更新
        if (label_data.id in this.labeldata) {
            label_data = this.labeldata[label_data.id];
            await this.loadLabelEx(label_data);
            this.labeldata_pages[pageIndex][inPageIndex] = label_data;
        } else {
            await this.loadLabelEx(label_data);
            this.labeldata[label_data.id] = label_data;
        }

        return label_data;
    }

    // 初次从服务端获取数据，补充一些必要信息，包括标注结果的解析
    async loadLabelEx(label_data) {
        // 补充图像的url
        label_data.url = BASE_IMAGES_URL + label_data.image_url;
        // console.log('loadLabelEx label_data.url = ', label_data.url);
        let tokens = label_data.image_url.split('/');
        label_data.name = tokens[tokens.length - 1];

        // 补充标注结果url并加载数据
        // console.log('loadLabelEx label_data = ', label_data);
        if (label_data.label_result) {
            return;
        }
        // console.log('loadLabelEx fetch new json file');
        let autolabel_url = BASE_LABELS_URL + label_data.autolabel_url;
        let label_url = BASE_LABELS_URL + label_data.label_url;
        let label_result = [];
        // console.log(`label_url = |${label_url}|`);
        // 如果存在手工标注的结果则直接加载，如果没有则判断是否存在自动标注结果
        // 有自动标注结果就拷贝到手工标注数据里面
        try {
            if (label_data.label_url) {
                let resp = await axios.get(label_url);
                label_result = resp.data;
            } else if (label_data.autolabel_url) {
                let resp = await axios.get(autolabel_url);
                label_result = resp.data;
            }
        } catch (error) {
            console.log('捕获到异常，错误=', error);
        }

        label_data.label_result = await createLabel(this.dataset_type);
        label_data.label_result.fromJson(label_result);

        return label_data;
    }

    // 保存手工标注的结果，更新本地数据以及云端数据
    async saveLabelData(label_data_id, label_result) {
        // console.log('saveLabelData label_result = ', label_result);
        // 更新云端数据
        let response = await API.cloud.labeldata.saveLabelData(label_data_id, label_result);
        if ('image_url' in response) {
            let new_label_data = await this.loadLabelEx(response);
            // console.log('saveLabelData new_label_data = ', new_label_data);
            // 更新本地数据
            this.labeldata[label_data_id] = new_label_data;
            return new_label_data;
        } else {
            return {};
        }
    }

    // 自动化标注云端的图片，返回标注的结果
    async autolabelImage(label_data_id) {
        // console.log('autolabelImage label_data_id = ', label_data_id);
        let response = await API.cloud.autolabel.autolabelImage(label_data_id);
        if ('image_url' in response) {
            let new_label_data = await this.loadLabelEx(response);
            // console.log('autolabelImage new_label_data = ', new_label_data);
            // 更新本地数据
            this.labeldata[label_data_id] = new_label_data;
            return new_label_data;
        } else {
            return {};
        }
    }
}

export default new LabelStorageCloud();
